#include <stdio.h>
#include <stdlib.h>
#include <sthread.h>
#include <block.h>
#include <logrw.h>
#include <assert.h>

#define BLKSIZE 2
#define NUMBLK 3
#define NUMREGS 2

// Fills a block with "number" and "version" on its first two integers 
// positions and then writes it on position "number"
#define WRITEBLK(number, version) (block[0]=(char)number, block[1]=(char)version, logrw_write(lbks,number, (char *)block))
// Reads the block indexed by "number", and prints its first two positions: the "number" 
// and "version" of the block
#define READBLK(number) (logrw_read(lbks, number, block), dump_block(block))
// Dumps the logblock and block memories: the logblock is just a index:number structure while the
// block memory is a triple index:first position:second position
#define DUMP() (logrw_dump(lbks), logrw_dump_all_registers(lbks))

logrw_struct_t *lbks;
int write_times;

void *thread_A(void * _lbks) {
	int i=0;
	int j=0;
	char *block = (char*)malloc(BLKSIZE);
	for (i = 0; i < write_times; i++) {
		WRITEBLK(j, i);
		j = (j+1) % NUMREGS;
	}

	sthread_exit(NULL);
	return NULL;
}


int main(int argc, const char * argv[]) {
	void *ret=NULL;
	int num_thr;
	int i;
	sthread_init();

	lbks = logrw_init(NUMREGS, NUMBLK, BLKSIZE);
	if (argc > 1) {
		num_thr = atoi(argv[1]);
		write_times = atoi(argv[2]);
	} else {
		num_thr = 1;
		write_times = 1;
	}
	sthread_t *threads = (sthread_t*)malloc(sizeof(sthread_t)*num_thr);
	for(i=0; i < num_thr; i++){
		assert( NULL != (threads[i]= sthread_create(thread_A, lbks, 1, 1, 0)));

	}
	for(i=0; i < num_thr; i++){
		sthread_join(threads[i],ret);
	}
	free(threads);
	logrw_free(lbks);
	return 0;
}

